{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "3xW4O0zuKfWD"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "from openai import OpenAI, pydantic_function_tool\n",
        "import rich\n",
        "import requests\n",
        "import json\n",
        "from pydantic import BaseModel, Field\n",
        "from google.colab import userdata"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "api_key = userdata.get('OPENAI_API_KEY')\n",
        "MODEL = \"gpt-4o-mini\"\n",
        "\n",
        "openai = OpenAI(api_key=api_key)"
      ],
      "metadata": {
        "id": "vUydnLeLKs03"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "This is the same example, but it uses a new conversation state in the Responses API."
      ],
      "metadata": {
        "id": "sN9xXAjSgWOw"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "**Looping through tool calls in cases where they are received in multiple steps. For scenarios involving multiple tool calls, like GetWeather and SendEmail, where each tool might be called multiple times, we need to create logic that can send and receive messages from the model in multiple stages, making a final call to receive the complete response.**"
      ],
      "metadata": {
        "id": "blCx6gu1Vl46"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "The Pydantic-generated function structure is acceptable in OpenAI's Chat API, but the Responses API requires a slightly different structure."
      ],
      "metadata": {
        "id": "nznKPApuXC9z"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "class GetWeather(BaseModel):\n",
        "    latitude: float = Field(..., description=\"Latitude of the location\")\n",
        "    longitude: float = Field(..., description=\"Longitude of the location\")\n",
        "\n",
        "class SendEmail(BaseModel):\n",
        "    to: str = Field(..., description=\"Email address of the recipient\")\n",
        "    subject: str = Field(..., description=\"Subject of the email\")\n",
        "    body: str = Field(..., description=\"Body of the email\")\n",
        "\n",
        "def get_weather(latitude, longitude):\n",
        "    response = requests.get(f\"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}&current=temperature_2m,wind_speed_10m&hourly=temperature_2m,relative_humidity_2m,wind_speed_10m\")\n",
        "    data = response.json()\n",
        "    print(f\"get_weather function called to get weather for latitude = {latitude}, longitude = {longitude}\")\n",
        "    print(f\"And result is  = {data['current']['temperature_2m']}\")\n",
        "    return data['current']['temperature_2m']\n",
        "\n",
        "def send_email(to, subject, body):\n",
        "    print(f\"Tool send_email Sending email to {to} with subject {subject}\")\n",
        "    print(f\"Body: {body}\")\n",
        "    print(f\"Email Tool call completed\")\n",
        "    return \"Email Sent\"\n",
        "\n",
        "rich.print(pydantic_function_tool(GetWeather))\n",
        "rich.print(pydantic_function_tool(SendEmail))\n",
        "\n",
        "# creating list of tools here because it can be used in both Chat API and Responses API\n",
        "tools = [pydantic_function_tool(SendEmail), pydantic_function_tool(GetWeather)]"
      ],
      "metadata": {
        "id": "qvJhp-k5XEmW",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 577
        },
        "outputId": "29efdb67-7860-4843-acbd-0704c0e54da8"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "\u001b[1m{\u001b[0m\n",
              "    \u001b[32m'type'\u001b[0m: \u001b[32m'function'\u001b[0m,\n",
              "    \u001b[32m'function'\u001b[0m: \u001b[1m{\u001b[0m\n",
              "        \u001b[32m'name'\u001b[0m: \u001b[32m'GetWeather'\u001b[0m,\n",
              "        \u001b[32m'strict'\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n",
              "        \u001b[32m'parameters'\u001b[0m: \u001b[1m{\u001b[0m\n",
              "            \u001b[32m'properties'\u001b[0m: \u001b[1m{\u001b[0m\n",
              "                \u001b[32m'latitude'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'description'\u001b[0m: \u001b[32m'Latitude of the location'\u001b[0m, \u001b[32m'title'\u001b[0m: \u001b[32m'Latitude'\u001b[0m, \u001b[32m'type'\u001b[0m: \u001b[32m'number'\u001b[0m\u001b[1m}\u001b[0m,\n",
              "                \u001b[32m'longitude'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'description'\u001b[0m: \u001b[32m'Longitude of the location'\u001b[0m, \u001b[32m'title'\u001b[0m: \u001b[32m'Longitude'\u001b[0m, \u001b[32m'type'\u001b[0m: \u001b[32m'number'\u001b[0m\u001b[1m}\u001b[0m\n",
              "            \u001b[1m}\u001b[0m,\n",
              "            \u001b[32m'required'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'latitude'\u001b[0m, \u001b[32m'longitude'\u001b[0m\u001b[1m]\u001b[0m,\n",
              "            \u001b[32m'title'\u001b[0m: \u001b[32m'GetWeather'\u001b[0m,\n",
              "            \u001b[32m'type'\u001b[0m: \u001b[32m'object'\u001b[0m,\n",
              "            \u001b[32m'additionalProperties'\u001b[0m: \u001b[3;91mFalse\u001b[0m\n",
              "        \u001b[1m}\u001b[0m\n",
              "    \u001b[1m}\u001b[0m\n",
              "\u001b[1m}\u001b[0m\n"
            ],
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">{</span>\n",
              "    <span style=\"color: #008000; text-decoration-color: #008000\">'type'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'function'</span>,\n",
              "    <span style=\"color: #008000; text-decoration-color: #008000\">'function'</span>: <span style=\"font-weight: bold\">{</span>\n",
              "        <span style=\"color: #008000; text-decoration-color: #008000\">'name'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'GetWeather'</span>,\n",
              "        <span style=\"color: #008000; text-decoration-color: #008000\">'strict'</span>: <span style=\"color: #00ff00; text-decoration-color: #00ff00; font-style: italic\">True</span>,\n",
              "        <span style=\"color: #008000; text-decoration-color: #008000\">'parameters'</span>: <span style=\"font-weight: bold\">{</span>\n",
              "            <span style=\"color: #008000; text-decoration-color: #008000\">'properties'</span>: <span style=\"font-weight: bold\">{</span>\n",
              "                <span style=\"color: #008000; text-decoration-color: #008000\">'latitude'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'description'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'Latitude of the location'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'Latitude'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'type'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'number'</span><span style=\"font-weight: bold\">}</span>,\n",
              "                <span style=\"color: #008000; text-decoration-color: #008000\">'longitude'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'description'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'Longitude of the location'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'Longitude'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'type'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'number'</span><span style=\"font-weight: bold\">}</span>\n",
              "            <span style=\"font-weight: bold\">}</span>,\n",
              "            <span style=\"color: #008000; text-decoration-color: #008000\">'required'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'latitude'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'longitude'</span><span style=\"font-weight: bold\">]</span>,\n",
              "            <span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'GetWeather'</span>,\n",
              "            <span style=\"color: #008000; text-decoration-color: #008000\">'type'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'object'</span>,\n",
              "            <span style=\"color: #008000; text-decoration-color: #008000\">'additionalProperties'</span>: <span style=\"color: #ff0000; text-decoration-color: #ff0000; font-style: italic\">False</span>\n",
              "        <span style=\"font-weight: bold\">}</span>\n",
              "    <span style=\"font-weight: bold\">}</span>\n",
              "<span style=\"font-weight: bold\">}</span>\n",
              "</pre>\n"
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "\u001b[1m{\u001b[0m\n",
              "    \u001b[32m'type'\u001b[0m: \u001b[32m'function'\u001b[0m,\n",
              "    \u001b[32m'function'\u001b[0m: \u001b[1m{\u001b[0m\n",
              "        \u001b[32m'name'\u001b[0m: \u001b[32m'SendEmail'\u001b[0m,\n",
              "        \u001b[32m'strict'\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n",
              "        \u001b[32m'parameters'\u001b[0m: \u001b[1m{\u001b[0m\n",
              "            \u001b[32m'properties'\u001b[0m: \u001b[1m{\u001b[0m\n",
              "                \u001b[32m'to'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'description'\u001b[0m: \u001b[32m'Email address of the recipient'\u001b[0m, \u001b[32m'title'\u001b[0m: \u001b[32m'To'\u001b[0m, \u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m\u001b[1m}\u001b[0m,\n",
              "                \u001b[32m'subject'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'description'\u001b[0m: \u001b[32m'Subject of the email'\u001b[0m, \u001b[32m'title'\u001b[0m: \u001b[32m'Subject'\u001b[0m, \u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m\u001b[1m}\u001b[0m,\n",
              "                \u001b[32m'body'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'description'\u001b[0m: \u001b[32m'Body of the email'\u001b[0m, \u001b[32m'title'\u001b[0m: \u001b[32m'Body'\u001b[0m, \u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m\u001b[1m}\u001b[0m\n",
              "            \u001b[1m}\u001b[0m,\n",
              "            \u001b[32m'required'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'to'\u001b[0m, \u001b[32m'subject'\u001b[0m, \u001b[32m'body'\u001b[0m\u001b[1m]\u001b[0m,\n",
              "            \u001b[32m'title'\u001b[0m: \u001b[32m'SendEmail'\u001b[0m,\n",
              "            \u001b[32m'type'\u001b[0m: \u001b[32m'object'\u001b[0m,\n",
              "            \u001b[32m'additionalProperties'\u001b[0m: \u001b[3;91mFalse\u001b[0m\n",
              "        \u001b[1m}\u001b[0m\n",
              "    \u001b[1m}\u001b[0m\n",
              "\u001b[1m}\u001b[0m\n"
            ],
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">{</span>\n",
              "    <span style=\"color: #008000; text-decoration-color: #008000\">'type'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'function'</span>,\n",
              "    <span style=\"color: #008000; text-decoration-color: #008000\">'function'</span>: <span style=\"font-weight: bold\">{</span>\n",
              "        <span style=\"color: #008000; text-decoration-color: #008000\">'name'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'SendEmail'</span>,\n",
              "        <span style=\"color: #008000; text-decoration-color: #008000\">'strict'</span>: <span style=\"color: #00ff00; text-decoration-color: #00ff00; font-style: italic\">True</span>,\n",
              "        <span style=\"color: #008000; text-decoration-color: #008000\">'parameters'</span>: <span style=\"font-weight: bold\">{</span>\n",
              "            <span style=\"color: #008000; text-decoration-color: #008000\">'properties'</span>: <span style=\"font-weight: bold\">{</span>\n",
              "                <span style=\"color: #008000; text-decoration-color: #008000\">'to'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'description'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'Email address of the recipient'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'To'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'type'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'string'</span><span style=\"font-weight: bold\">}</span>,\n",
              "                <span style=\"color: #008000; text-decoration-color: #008000\">'subject'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'description'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'Subject of the email'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'Subject'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'type'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'string'</span><span style=\"font-weight: bold\">}</span>,\n",
              "                <span style=\"color: #008000; text-decoration-color: #008000\">'body'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'description'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'Body of the email'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'Body'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'type'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'string'</span><span style=\"font-weight: bold\">}</span>\n",
              "            <span style=\"font-weight: bold\">}</span>,\n",
              "            <span style=\"color: #008000; text-decoration-color: #008000\">'required'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'to'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'subject'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'body'</span><span style=\"font-weight: bold\">]</span>,\n",
              "            <span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'SendEmail'</span>,\n",
              "            <span style=\"color: #008000; text-decoration-color: #008000\">'type'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'object'</span>,\n",
              "            <span style=\"color: #008000; text-decoration-color: #008000\">'additionalProperties'</span>: <span style=\"color: #ff0000; text-decoration-color: #ff0000; font-style: italic\">False</span>\n",
              "        <span style=\"font-weight: bold\">}</span>\n",
              "    <span style=\"font-weight: bold\">}</span>\n",
              "<span style=\"font-weight: bold\">}</span>\n",
              "</pre>\n"
            ]
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Responses API\n",
        "\n",
        "https://platform.openai.com/docs/guides/function-calling?api-mode=responses"
      ],
      "metadata": {
        "id": "tCzSosP5K-JR"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "To use pydantic-generated function, we need to use `openai.responses.parse()` function call\n",
        "\n",
        "https://github.com/openai/openai-python/blob/main/examples/responses/structured_outputs_tools.py"
      ],
      "metadata": {
        "id": "X__yLWt7aIOU"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Using new way of conversation state by sending perivous reponse id"
      ],
      "metadata": {
        "id": "p87WEKKmcB9L"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "Defining a function that will receive list of messages and call the Responses API"
      ],
      "metadata": {
        "id": "bsFB-WT1feBz"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Function to call OpenAI's Chat API\n",
        "def call_response_api(messages, previous_response_id):\n",
        "    response = openai.responses.parse(\n",
        "        model=MODEL,\n",
        "        # Passing the previous_response_id, for first call it will be None\n",
        "        previous_response_id=previous_response_id,\n",
        "        input=messages,\n",
        "        tools = tools\n",
        "    )\n",
        "    return response"
      ],
      "metadata": {
        "id": "gUjC_PQCcETm"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "Defining a function `handle_tool_call_responses` in which we will loop through the tool_calls, invoke the corresponding functions, and update the response. Plus, we will append a new message for each function call to promptMessages."
      ],
      "metadata": {
        "id": "V7TeuUMvcJCY"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# The only difference in this section is that we are not adding tool calls in promptMessages.\n",
        "\n",
        "def handle_tool_call_responses(promptMessages, responseFromAPI):\n",
        "    isFunctionCall = False\n",
        "    for tool_call in responseFromAPI.output:\n",
        "        if tool_call.type == \"function_call\": # check if the output's type is function_call\n",
        "            # As we don't have finish_reason property in Responses API that indicate tool_calls or stop\n",
        "            # so we will use isFunctionCall flag to keep track it function call is received\n",
        "            isFunctionCall = True\n",
        "            name = tool_call.name\n",
        "            arguments = json.loads(tool_call.arguments)\n",
        "            if name == \"SendEmail\":\n",
        "                result = send_email(**arguments)\n",
        "            elif name == \"GetWeather\":\n",
        "                result = get_weather(**arguments)\n",
        "            new_message = {\n",
        "                \"type\": \"function_call_output\",\n",
        "                \"call_id\": tool_call.call_id,\n",
        "                \"output\": str(result)\n",
        "            }\n",
        "\n",
        "            # del tool_call.parsed_arguments   # Not needed now because we are using response.id\n",
        "            # promptMessages.append(tool_call) # Not needed now because we are using response.id\n",
        "            promptMessages.append(new_message)\n",
        "    return isFunctionCall"
      ],
      "metadata": {
        "id": "ds6RgacxcL8a"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "The `handle_response_api()` function handles communication with a Responses API in a loop, processing user prompts, handling tool calls, and iterating until a final response is received."
      ],
      "metadata": {
        "id": "FSgCYJWaf0N8"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# The only difference in this section is that we are sending response.id in the call_response_api function\n",
        "def handle_response_api(prompt):\n",
        "    messages=[\n",
        "        {\"role\": \"developer\", \"content\": \"You are a helpful assistant, you can send email about weather in a city. Email should be courteous and professional.\"},\n",
        "        {\"role\": \"user\", \"content\": prompt}\n",
        "    ]\n",
        "\n",
        "    response = call_response_api(messages, None) # sending None for the first time\n",
        "    counter = 0 # counter to keep track of the number times we receive tool calls from model\n",
        "\n",
        "    while True:\n",
        "        print()\n",
        "        print(\"Iteration Started\")\n",
        "        print(\"Response Status = \",response.status)\n",
        "        # rich.print(\"response.output = \",response.output)\n",
        "        # We don't have finish_reason in response from Response API, and status always be \"completed\"\n",
        "\n",
        "        # Emptying the messages array because we are sending the previous response id,\n",
        "        # therefore we don't need to send the previous message\n",
        "        messages = []\n",
        "        isFunctionCalled = handle_tool_call_responses(messages, response)\n",
        "        if isFunctionCalled:\n",
        "            counter += 1\n",
        "            # Uncomment below line to see the messages\n",
        "            # rich.print(messages)\n",
        "            response = call_response_api(messages, response.id) # sending the response.id\n",
        "        else:\n",
        "            print(\"-------\")\n",
        "            print(\"Number of times Tool calls received from model are = \",counter)\n",
        "            print()\n",
        "            print(response.output_text)\n",
        "            print(\"-------\")\n",
        "            break"
      ],
      "metadata": {
        "id": "6yllPhl4f0fJ"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "Call `handle_response_api` function with different inputs"
      ],
      "metadata": {
        "id": "DaiKz9TXf77h"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Check result of each prompt\n",
        "handle_response_api(\"Send an email to shan@gmail.com and hello@gmail.com about weather in Karachi\")\n",
        "# handle_response_api(\"Send an email about weather in Karachi to first@gmail.com and second@gmail.com\") # This prompt is giving error somehow\n",
        "# handle_response_api(\"send an email about weather in Karachi and Lahore to both shan@gmail.com and hello@gmail.com\")\n",
        "# handle_response_api(\"send an email about weather in Karachi and Lahore to shan@gmail.com and hello@gmail.com\")"
      ],
      "metadata": {
        "id": "9u6Fog3bf8MU",
        "outputId": "a068160b-2170-420d-93e1-49ba4b98b09c",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "Iteration Started\n",
            "Response Status =  completed\n",
            "get_weather function called to get weather for latitude = 24.8607, longitude = 67.0011\n",
            "And result is  = 25.4\n",
            "\n",
            "Iteration Started\n",
            "Response Status =  completed\n",
            "Tool send_email Sending email to shan@gmail.com with subject Weather Update for Karachi\n",
            "Body: Dear Shan,\n",
            "\n",
            "I hope this message finds you well. \n",
            "\n",
            "I wanted to provide you with a brief update on the weather in Karachi. Currently, the temperature is approximately 25.4°C. Please make sure to stay hydrated and take care of yourself while enjoying the pleasant weather.\n",
            "\n",
            "Best regards,\n",
            "\n",
            "[Your Name]\n",
            "Email Tool call completed\n",
            "\n",
            "Iteration Started\n",
            "Response Status =  completed\n",
            "Tool send_email Sending email to hello@gmail.com with subject Weather Update for Karachi\n",
            "Body: Dear Recipient,\n",
            "\n",
            "I hope this message finds you well. \n",
            "\n",
            "I wanted to provide you with a brief update on the weather in Karachi. Currently, the temperature is approximately 25.4°C. Please make sure to stay hydrated and take care of yourself while enjoying the pleasant weather.\n",
            "\n",
            "Best regards,\n",
            "\n",
            "[Your Name]\n",
            "Email Tool call completed\n",
            "\n",
            "Iteration Started\n",
            "Response Status =  completed\n",
            "-------\n",
            "Number of times Tool calls received from model are =  3\n",
            "\n",
            "I have sent the weather update emails to both Shan at shan@gmail.com and the recipient at hello@gmail.com. If you need anything else, feel free to ask!\n",
            "-------\n"
          ]
        }
      ]
    }
  ]
}